package com.irisking.server.coder;

import java.util.List;

import com.irisking.server.entity.TransforData;
import com.irisking.server.utils.ConvertUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

/**
 * 数据包解码器
 * <pre>
 * 数据包格式
 * +——----——+——-----——+——----——+——----——+——-----——+——-----——+
 * |  同步头	   |  模块号     |  命令号    |   长度    |   数据     |     校验    |
 * +——----——+——-----——+——----——+——----——+——-----——+——-----——+
 * </pre>
 * 同步头 2字节
 * 模块号 2字节
 * 命令号 2字节
 * 长度 4字节(数据部分占有字节数量)
 * 校验 2字节
 * @author -weiz-
 *
 */
public class RequestDecoder extends ByteToMessageDecoder {
	
	/**
	 * 数据包基本长度
	 */
	public static int BASE_LENTH = 2 + 2 + 2 + 4 + 2;

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
		while(true) {
			if (buffer.readableBytes() >= BASE_LENTH) {
				//第一个可读数据包的起始位置
				int beginIndex;
				while (true) {
					//包头开始游标点
					//System.out.println("总长度:" + buffer.readableBytes());
					beginIndex = buffer.readerIndex();
					//System.out.println("beginIndex:" + beginIndex);
					//标记初始读游标位置
					buffer.markReaderIndex();
					short header_flag = buffer.readShort();
					if (header_flag == ConstantValue.HEADER_FLAG) {
						System.out.println("header_flag:" + header_flag);
						break;
					}

					//System.out.println("未读到包头标识略过一个字节:" + buffer.readerIndex());
					//未读到包头标识略过一个字节
					buffer.resetReaderIndex();
					buffer.readByte();
					//不满足
					if (buffer.readableBytes() < BASE_LENTH) {
						return;
					}
				}

				//System.out.println("开始读取全部数据:" + buffer.readerIndex());
				//读取命令号
				byte[] commCodeData = new byte[2];
				buffer.readBytes(commCodeData);
				short commCode =ConvertUtil.toShort(commCodeData);

				//读取命令号
				byte[] commSubCodeData = new byte[2];
				buffer.readBytes(commSubCodeData);
				short commSubCode =ConvertUtil.toShort(commSubCodeData);

				//System.out.println("module:" + commCode + ",cmd:" + commSubCode);
				//读取数据长度
				byte[] lenData = new byte[4];
				buffer.readBytes(lenData);
				int length =ConvertUtil.toInt(lenData);

				//System.out.println("lenth:" + length + ",index:" + buffer.readerIndex());
				if (length < 0) {
					ctx.channel().close();
				}
				//数据包还没到齐
				if (buffer.readableBytes() < length) {
					buffer.readerIndex(beginIndex);
					return;
				}
				//读数据部分
				byte[] data = new byte[length];
				buffer.readBytes(data);
				//System.out.println("check,index:" + buffer.readerIndex());
				// 校验码
				byte[] checkData = new byte[2];
				buffer.readBytes(checkData);
				int check = ConvertUtil.toInt(checkData);
				//System.out.println("check:" + check);
				//System.out.println("读完,index:" + buffer.readerIndex());

				TransforData message = new TransforData();
				message.setCommCode(commCode);
				message.setCommSubCode(commSubCode);
				message.setData(data);
				//解析出消息对象，继续往下面的handler传递
				out.add(message);
				//System.out.println("解析出消息对象，继续往下面的handler传递:" + buffer.readerIndex());
			} else {
				break;
			}
		}

		//数据不完整，等待完整的数据包
		return;
	}
}
